Handling Interrupts

This actually is very simple. gcc provides the means to mark a function as an interrupt service routine, namely prefixing a function with __attribute__(interrupt). So, something like this:

__attribute__((interrupt)) duart_interrupt(void) {
    /* Handle the interrupt */

}

But there's a macro in machine.h to help, so you could replace the above with:

#include <machine.h>

ISR duart_interrupt(void) {
    /* Handle the interrupt */

}

gcc knows that functions declared using either of the above methods should end with the rte rather than rts instruction.

Example

#include <stdio.h>
#include <machine.h>

static unsigned int ticks = 0;

ISR isr(void) {
    ticks++;

    *pit_tsr = 1;
}

void scan() {
    static int lednum = 2;
    static int delta = 1;

    /* create simple visual effect with some of the leds */
    clear_led(lednum);

    lednum += delta;
    if ((lednum < 2) || (lednum > 7)) {
        delta = -delta;
        lednum += delta;
        lednum += delta;
    }

    set_led(lednum);
}

int main(void) {
    unsigned char ivr = *pit_tivr;

    int loop = 0;

    printf("Press any key...\n");

    _pit_set_counter(1000);
    *pit_tsr = 1;

    set_isr_handler(ivr, isr);

    /* Wait for a keypress */
    while (!_char_available()) {
        printf("%08x\r", ticks);

        loop++;
        if (loop == 100) {
            scan();
            loop = 0;
        }
    }

    _getchar();
}
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9